home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / ma93 / Quick / Quick.txt < prev   
Encoding:
Text File  |  1993-05-19  |  8.4 KB  |  185 lines

  1. (c) Copyright 1993 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and is provided "as is" without warranty of any kind, either expressed
  4. or implied.  The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7.  
  8. Quick Interrupts
  9.  
  10. by Michael Sinz
  11.  
  12.  
  13.     [Editor's note: This article was written from the
  14.     programmer's perspective, and doesn't discuss any of
  15.     the hardware issues.  See the ``Appendix K: Zorro
  16.     Expansion Bus'' section of the third edition of the
  17.     Amiga Hardware Reference Manual for more information.]
  18.  
  19.  
  20. One of the features of the Zorro III bus is the Quick Interrupt, also
  21. known as the vectored interrupt.  This feature allows Zorro III
  22. hardware to supply a vector number to the system when an interrupt
  23. occurs.  The system uses this vector number to go directly to an
  24. interrupt routine.
  25.  
  26.  
  27. Conventional Amiga Interrupts
  28.  
  29. The Amiga handles normal interrupts from Zorro II cards using an
  30. interrupt server chain.  There are two interrupts available from the
  31. Zorro II bus, the PORTS and EXTER interrupt server chains.  If a driver
  32. for a Zorro II card needs to use an interrupt, it adds an interrupt
  33. routine to the appropriate chain.  When the interrupt occurs, Exec
  34. calls each routine in the interrupt chain, which are sorted in priority
  35. order.  Exec continues until it finds the routine that corresponds to
  36. the device that triggered the interrupt.
  37.  
  38. The server chain allows several routines to share a single interrupt.
  39. This means that several devices trigger the same interrupt, so each
  40. interrupt routine must do some processing to determine if its card
  41. triggered the interrupt or if some other source caused the interrupt.
  42. For example, an interrupt routine might examine a register on its card
  43. to determine that the card triggered the interrupt.
  44.  
  45. Although this scheme allows unrelated pieces of software to easily
  46. share an interrupt, it can make the interrupt overhead rather high.
  47. These two interrupt server chains also handle interrupts from the CIA
  48. chips, which are used to trigger a variety of events.  As a result,
  49. these server chains can contain a multitude of interrupt routines.
  50.  
  51. Consider what happens when a Zorro II card generates a PORTS interrupt.
  52. Exec has to perform some set up and then step through the PORTS server
  53. chain.  Exec calls each interrupt routine in priority order looking for
  54. the routine that services this interrupt.  If there are 20 interrupt
  55. routines of higher priority than the card's interrupt routine in the
  56. server chain, Exec has to call 20 other routines before it gets to the
  57. correct routine.
  58.  
  59.  
  60. Zorro III Quick Interrupts
  61.  
  62. Quick interrupts avoid the overhead involved in Exec's interrupt server
  63. chains.  Exec only helps set up the quick interrupt, which it does via
  64. the exec.library function ObtainQuickVector() (see the Autodoc at the
  65. end of this article).  Once Exec has set up the quick interrupt
  66. routine, it does not intervene.  Unlike conventional Amiga interrupt
  67. routines, which are called as subroutines from Exec's main interrupt
  68. code, the Amiga jumps directly to the quick interrupt routine using a
  69. private vector.  This behavior requires quick interrupt routines to
  70. take some special precautions.
  71.  
  72. There are two important differences between a conventional Amiga
  73. interrupt routine and a quick quick interrupt routine.  A quick
  74. interrupt routine must save and restore all of the registers it
  75. changes, including D0, D1, A0, and A1.  It must do this because, unlike
  76. regular interrupt routines, Exec doesn't do it for you.  Also, a quick
  77. interrupt routine ends with a RTE (return from exception) instruction.
  78.  
  79. If your quick interrupt routine is 100% self-contained and does not
  80. access any operating system structures or routines, then the work is
  81. rather simple.  Just save the registers you use, perform your interrupt
  82. processing, restore the registers, and end with an RTE.  If, however,
  83. the routine needs to call the OS or use an OS structure, it must check
  84. if the interrupt has been delayed.  This is necessary in case the
  85. interrupt hit the CPU just after the CPU had told the hardware to hold
  86. off interrupts (see the Autodoc for ObtainQuickVector() to find out how
  87. to perform this test).
  88.  
  89. As the Amiga OS is a dynamic operating system, quick interrupts are
  90. allocated by the OS.  If your hardware/software wants to use a quick
  91. interrupt, it must allocate a vector with ObtainQuickVector().  This
  92. routine accepts a pointer to the quick interrupt code (not a pointer to
  93. an Interrupt structure).  If Exec installed the vector,
  94. ObtainQuickVector() returns the vector number.  When the quick
  95. interrupt occurs, the Zorro III card sends this vector number to the
  96. CPU, which tells the CPU where the interrupt code is.
  97.  
  98. ObtainQuickVector() returns 0 if there are no more vectors.  Since the
  99. number of vectors is limited, any Zorro III device that uses quick
  100. interrupts must be able to fall back to the Amiga's conventional
  101. interrupt scheme.
  102.  
  103. The LVO for ObtainQuickVector() was added for V39, but it was not fully
  104. implemented until after the initial release.  This means the OS that
  105. currently ships with the Amiga 4000 and Amiga 1200, Release 3.00, will
  106. always return 0 (no SetPatch currently exists to correct this, but a
  107. future SetPatch may do so).  ObtainQuickVector() only works in the
  108. developer releases of the OS that follwed the initial release.  Since a
  109. Zorro III device driver must handle the case where it cannot obtain a
  110. vector, this function should never cause a hardware product to fail.
  111. There is no reliable way to obtain a vector before V39.
  112.  
  113.  
  114. exec.library/ObtainQuickVector                 exec.library/ObtainQuickVector
  115.  
  116.    NAME
  117.         Function to obtain an install a Quick Interrupt vector            (V39)
  118.  
  119.    SYNOPSIS
  120.         vector=ObtainQuickVector(interruptCode)
  121.         d0                       a0
  122.  
  123.         ULONG ObtainQuickVector(APTR);
  124.  
  125.    FUNCTION
  126.         This function will install the code pointer into the quick interrupt
  127.         vector it allocates and returns to you the interrupt vector that
  128.         your Quick Interrupt system needs to use.
  129.  
  130.         This function may also return 0 if no vectors are available.  Your
  131.         hardware should be able to then fall back to using the shared
  132.         interrupt server chain should this happen.
  133.  
  134.         The interrupt code is a direct connect to the physical interrupt.
  135.         This means that it is the responsibility of your code to do all
  136.         of the context saving/restoring required by interrupt code.
  137.  
  138.         Also, due to the performance of the interrupt controller, you may
  139.         need to also watch for "false" interrupts.  These are interrupts
  140.         that come in just after a DISABLE.  The reason this happens is
  141.         because the interrupt may have been posted before the DISABLE
  142.         hardware access is completed.  For example:
  143.  
  144.         myInt:          move.l  d0,-(sp)        ; Save d0...
  145.                         move.w  _intenar,d0     ; Get interrupt enable state
  146.                         btst.l  #INTB_INTEN,d0  ; Check if pending disable
  147.                         bne.s   realInt         ; If not, do real one...
  148.         exitInt:        move.l  (sp)+,d0        ; Restore d0
  149.                         rte                     ; Return from int...
  150.         ;
  151.         realInt:        ; Now do your int code...  d0 is already saved
  152.                         ; ALL other registers need to be saved if needed
  153.                         ; This includes a0/a1/d0/d1 as this is an interrupt
  154.                         ; and not a function call...
  155.                         ;
  156.                         bra.s   exitInt         ; Exit interrupt...
  157.  
  158.         If your interrupt will not play with system (OS) structures and your
  159.         own structures are safe to play with you do not need to check for
  160.         the disable.  It is only needed for when the system is in disable but
  161.         that "one last interrupt" still got through.
  162.  
  163.    NOTE
  164.         This function was not implemented fully until V39.  Due to a miscue
  165.         it is not safe to call in V37 EXEC.  (Sorry)
  166.  
  167.    INPUTS
  168.         A pointer to your interrupt code.  This code is not an EXEC interrupt
  169.         but is directly connected to the hardware interrupt.  Thus, the
  170.         interrupt code must not modify any registers and must return via
  171.         an RTE.
  172.  
  173.    RESULTS
  174.         The 8-bit vector number used for Zorro-III Quick Interrupts
  175.         If it returns 0, no quick interrupt was allocatable.  The device
  176.         should at this point switch to using the shared interrupt server
  177.         method.
  178.  
  179.    SEE ALSO
  180.  
  181.  
  182.  
  183.  
  184.  
  185. ยง